use clap::{Arg, Command, ArgMatches};
use std::path::PathBuf;
use crate::config::Config;

pub struct Cli;

impl Cli {
    pub fn new() -> Self {
        Self
    }
    
    pub fn build_command() -> Command {
        Command::new("build_migrate")
            .version("0.1.0")
            .author("Build Migration Tool")
            .about("Convert between different build systems")
            .arg(
                Arg::new("input")
                    .short('i')
                    .long("input")
                    .value_name("FILE")
                    .help("Input file path (.sln or .vcxproj)")
                    .required_unless_present_any(["list-generators", "config"])
            )
            .arg(
                Arg::new("generator")
                    .short('g')
                    .long("generator")
                    .value_name("GENERATOR")
                    .help("Output generator (xmake)")
            )
            .arg(
                Arg::new("project-root")
                    .short('r')
                    .long("project-root")
                    .value_name("PATH")
                    .help("Project root directory (default: current directory)")
            )
            .arg(
                Arg::new("config")
                    .short('c')
                    .long("config")
                    .value_name("FILE")
                    .help("Configuration file path (.toml)")
            )
            .arg(
                Arg::new("verbose")
                    .short('v')
                    .long("verbose")
                    .help("Enable verbose logging")
                    .action(clap::ArgAction::SetTrue)
            )
            .arg(
                Arg::new("list-generators")
                    .long("list-generators")
                    .help("List available generators")
                    .action(clap::ArgAction::SetTrue)
            )
            .arg(
                Arg::new("no-clang-format")
                    .long("no-clang-format")
                    .help("Disable .clang-format file generation")
                    .action(clap::ArgAction::SetTrue)
            )
            .arg(
                Arg::new("no-clang-tidy")
                    .long("no-clang-tidy")
                    .help("Disable .clang-tidy file generation")
                    .action(clap::ArgAction::SetTrue)
            )
    }
    
    pub fn parse_args(&self, matches: &ArgMatches) -> crate::Result<Config> {
        let mut config = if let Some(config_path) = matches.get_one::<String>("config") {
            let path = PathBuf::from(config_path);
            if path.exists() {
                Config::from_file(&path)?
            } else {
                return Err(crate::BuildMigrateError::Config(
                    format!("Configuration file not found: {}", path.display())
                ));
            }
        } else {
            Config::default()
        };
        
        // 命令行参数覆盖配置文件设置
        if let Some(input) = matches.get_one::<String>("input") {
            config.input_path = PathBuf::from(input);
        } else if config.input_path == PathBuf::from(".") {
            return Err(crate::BuildMigrateError::Config(
                "Input path must be specified either in config file or command line".to_string()
            ));
        }
        
        if let Some(generator) = matches.get_one::<String>("generator") {
            config.generator = generator.clone();
        }

        if let Some(project_root) = matches.get_one::<String>("project-root") {
            config.project_root = Some(PathBuf::from(project_root));
        }

        if matches.get_flag("verbose") {
            config.log_level = "debug".to_string();
        }

        // 处理代码风格配置文件生成选项
        if matches.get_flag("no-clang-format") {
            config.code_style.generate_clang_format = false;
        }

        if matches.get_flag("no-clang-tidy") {
            config.code_style.generate_clang_tidy = false;
        }

        Ok(config)
    }
    
    pub fn init_logger(&self, log_level: &str) {
        let level = match log_level.to_lowercase().as_str() {
            "error" => log::LevelFilter::Error,
            "warn" => log::LevelFilter::Warn,
            "info" => log::LevelFilter::Info,
            "debug" => log::LevelFilter::Debug,
            "trace" => log::LevelFilter::Trace,
            _ => log::LevelFilter::Info,
        };
        
        env_logger::Builder::from_default_env()
            .filter_level(level)
            .format(|buf, record| {
                use std::io::Write;
                
                // 获取文件名和行号
                let file = record.file().unwrap_or("unknown");
                let line = record.line().unwrap_or(0);
                
                // 只保留文件名，不包含完整路径
                let filename = file.split('/').last().unwrap_or(file).split('\\').last().unwrap_or(file);
                
                writeln!(
                    buf,
                    "[{}] [{}:{}] - {}",
                    record.level(),
                    filename,
                    line,
                    record.args()
                )
            })
            .init();
    }
}
